﻿namespace NTLib.Core.Manipulators
{
    using NTLib.Core.Args;
    using NTLib.Core.ScopeLock;
    using System;

    /// <summary>
    /// Control the access to a specific value.
    /// If it need to be thread safe or not.
    /// </summary>
    public interface IAccessor
    {
        #region Properties

        /// <summary>
        /// Gets a value indicating whether this instance can set a value.
        /// </summary>
        /// <value>
        ///   <c>true</c> if this instance can set; otherwise, <c>false</c>.
        /// </value>
        bool CanSet { get; }

        /// <summary>
        /// Gets the type of the content.
        /// </summary>
        Type ContentType { get; }

        #endregion
    }

    /// <summary>
    /// Control the access to a specific value.
    /// If it need to be thread safe or not.
    /// </summary>
    /// <typeparam name="T">Value Type</typeparam>
    public interface IAccessor<T> : IAccessor
    {
        #region Event

        /// <summary>
        /// Occurs when the value changed.
        /// </summary>
        event Action<ValueChangedEventArgs<T>> ValueChanged;
        
        #endregion

        #region Methods

        /// <summary>
        /// Gets the value.
        /// </summary>
        T Get();

        /// <summary>
        /// Gets the scoped.
        /// </summary>
        ScopeLockItem<T> GetScoped();

        /// <summary>
        /// Sets the specified value.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="force">if set to <c>true</c> [force].</param>
        /// <returns>
        /// return <c>true</c> if the value have been changed; otherwise <c>false</c>
        /// </returns>
        bool Set(T value, bool force = false);

        #endregion
    }
}
